package com.itheima.d0_feedback.feedback3.src.d11_proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 被代理
 */
public class YangChaoYue implements SuperStar {

    @Override
    public String sing(String name) {
        System.out.println("杨超越唱响：" + name);
        return "谢谢！！";
    }

    @Override
    public void dance() {
        System.out.println("杨超越跳了一段社会摇！！");
    }
}

//程序员自己写的代理类
class YaoChaoYueProxy implements SuperStar {
    private YangChaoYue yangChaoYue;

    @Override
    public String sing(String name) {
        System.out.println("准备好话筒！！");
        String result = yangChaoYue.sing(name);
        return result;
    }

    @Override
    public void dance() {

    }
}

//让JDK生成
class Demo {
    public static void main(String[] args) {
        //多态
        SuperStar chaoYue = new YangChaoYue();

        SuperStar cyProxy = getProxy(chaoYue);//代理对象
        String result = cyProxy.sing("忘情水");
        //调用方法时，会触发invoke，此时method就是sing方法，参数args中就有 忘情水

        cyProxy.dance();

    }

    //生成的代理也是SuperStar的子类。
    public static SuperStar getProxy(SuperStar chaoYue) {
       return (SuperStar) Proxy.newProxyInstance(
                chaoYue.getClass().getClassLoader(), //类加载器
                chaoYue.getClass().getInterfaces(), //代理的父接口数组
                new InvocationHandler() {//代理逻辑书写的地方
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //代理调用方法时，就会触发invoke方法，method就是调用的方法对象，args调用方法时传入的实参

                        String methodName = method.getName();

                        //代理逻辑
                        if(methodName.equals("sing")) {
                            System.out.println("准备话筒！！");
                        } else if (methodName.equals("dance")) {
                            System.out.println("准备场地！！");
                        }


                        //String result = chaoYue.sing((String) args[0]);
                        Object result = method.invoke(chaoYue, args);

                        return result;
                    }
                }
        );
    }

}

